﻿/*
 * Copyright 2012 Tudor Olariu
 * SharePoint AfterWork
 * http://www.sharepoint-afterwork.com
 * http://www.sharepoint-afterwork.fr
 * 
 */

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.Office.Server.Search.WebControls;
using System.Xml.Linq;
using System.Linq;
using System.Web.UI.HtmlControls;

namespace SearchPreviewPrototype.SearchResultsPreview
{
    [ToolboxItemAttribute(false)]
    public class SearchResultsPreview : CoreResultsWebPart
    {

        #region Search Preview Properties

        [WebBrowsable(true)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(200)]
        [Category("Search Preview")]
        [WebDescription("Specifies the width of the pdf preview field. Defaults to 200.")]
        [WebDisplayName("Width")]
        public int PreviewBoxWidth { get; set; }

        [WebBrowsable(true)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(600)]
        [Category("Search Preview")]
        [WebDescription("Specifies the width of the pdf preview field. Defaults to 300.")]
        [WebDisplayName("Height")]
        public int PreviewBoxHeight { get; set; }


        [WebBrowsable(true)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(false)]
        [Category("Search Preview")]
        [WebDescription("Choose whether to show scroll bars in preview documents")]
        [WebDisplayName("Show scrollbars")]
        public bool ShowScrollBars { get; set; }


        [WebBrowsable(true)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(false)]
        [Category("Search Preview")]
        [WebDescription("Choose whether to show the toolbar in preview documents")]
        [WebDisplayName("Show toolbars")]
        public bool ShowToolBars { get; set; }

        [WebBrowsable(true)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(false)]
        [Category("Search Preview")]
        [WebDescription("Choose whether to show the statusbar in preview documents")]
        [WebDisplayName("Show status bar")]
        public bool ShowStatusBar { get; set; }

        [WebBrowsable(true)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(false)]
        [Category("Search Preview")]
        [WebDescription("Choose whether to show the document message bar preview documents")]
        [WebDisplayName("Show document message bar")]
        public bool ShowDocumentMessageBar { get; set; }

        [WebBrowsable(true)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(false)]
        [Category("Search Preview")]
        [WebDescription("Choose whether to show the document navigation pane and bar preview documents")]
        [WebDisplayName("Show navigation pane")]
        public bool ShowNavigationPane { get; set; }


        [WebBrowsable(true)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(false)]
        [Category("Search Preview")]
        [WebDescription("")]
        [WebDisplayName("Preview files in pop-up window")]
        public bool DialogPreview { get; set; }

        #endregion


        public SearchResultsPreview() : base()
        {
            //setup default values: will be overriden when the property values are retrieved from the webpart storage
            PreviewBoxHeight       = 300;
            PreviewBoxWidth        = 200;
            ShowScrollBars         = false;
            ShowToolBars           = false;
            ShowStatusBar          = false;
            ShowDocumentMessageBar = false;
            ShowNavigationPane     = false;
        }

        /// <summary>
        /// Returns the xml node to be injected in the original transformation.
        /// </summary>
        private XElement PreviewNode
        {
            get
            {
                return new XElement("div", new XAttribute("id", "{concat($currentId,'_preview')}"),
                                           new XAttribute("target", "previewBox"),

                                           new XAttribute("scrollbars", Convert.ToInt16(ShowScrollBars)),
                                           new XAttribute("toolbars",  Convert.ToInt16(ShowToolBars)),
                                           new XAttribute("statusbar",  Convert.ToInt16(ShowStatusBar)),
                                           new XAttribute("documentbar",  Convert.ToInt16(ShowDocumentMessageBar)),
                                           new XAttribute("navigationpane", Convert.ToInt16(ShowNavigationPane)),

                                           new XAttribute("previewwidth", PreviewBoxWidth),
                                           new XAttribute("previewheight", PreviewBoxHeight),

                                           new XAttribute("DialogPreview", Convert.ToInt16(DialogPreview)),

                                           new XAttribute("currentID", "{$currentId}"), 

                                           //note that {url} is a node present in the source xml file fed to the webpart
                                           new XAttribute("fileUrl", "{url}"), "&#160;");                
            }
        }

        /// <summary>
        /// Runs when the page is loaded
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            //register all the required components for client-side rendering
            Page.ClientScript.RegisterClientScriptInclude("jQuery", "/_layouts/SearchPreviewPrototype/jquery-1.7.1.min.js");
            Page.ClientScript.RegisterClientScriptInclude("jQueryUI", "/_layouts/SearchPreviewPrototype/jquery-ui-1.8.18.custom.min.js");

            Page.ClientScript.RegisterClientScriptInclude("pdfObject", "/_layouts/SearchPreviewPrototype/pdfobject.js");
            Page.ClientScript.RegisterClientScriptInclude("SearchPreview", "/_layouts/SearchPreviewPrototype/clientscript.js");

            //css link to jQuery's "lightness" theme
            HtmlLink css            = new HtmlLink();
            css.Href                = "/_layouts/SearchPreviewPrototype/themes/ui-lightness/jquery-ui-1.8.18.custom.css";
            css.Attributes["rel"]   = "stylesheet";
            css.Attributes["type"]  = "text/css";
            css.Attributes["media"] = "all";
            Page.Header.Controls.Add(css);
        }

        /// <summary>
        /// The Xsl used for the transformation of results.
        /// </summary>
        /// <remarks>The custom node is injected at runtime</remarks>
        public override string Xsl
        {   
            get
            {
                //automatically called after OnLoad
                if (string.IsNullOrEmpty(base.Xsl))
                    return string.Empty;

                try
                {
                    XDocument xslt = XDocument.Parse(base.Xsl);
                    //will insert the container right after the "Authors" row 
                    XElement metadataNode = (from divNode in xslt.Descendants("div")
                                             let classAttribute = divNode.Attribute("class")
                                             where classAttribute != null && classAttribute.Value == "srch-Metadata2"
                                             select divNode).FirstOrDefault();

                    if (metadataNode != null)
                    {
                        //found the matching node
                        metadataNode.Add(PreviewNode);
                    }

                    return xslt.ToString();
                }
                catch (Exception ex)
                {
                    //implement your own exception handling here
                    return base.Xsl;
                }
            }
            set
            {
                base.Xsl = value;
            }
        }
    }
}
